/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.webapp.controller.management.dishes;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.*;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.service.branchstores.MaterialCostDetailService;
import com.qinyeit.serviceapp.service.dishes.*;
import com.qinyeit.serviceapp.service.materials.MaterialService;
import com.qinyeit.serviceapp.service.materials.PurchaseSpecService;
import com.qinyeit.serviceapp.service.stores.StockService;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyeit.webapp.controller.management.BaseManagementController;
import com.qinyeit.webapp.utils.CurrentAccountUtils;
import com.qinyeit.webapp.utils.SearchableUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.utils.BeanConvertUtil;
import com.qinyetech.springstage.core.utils.JSONUtils;
import com.qinyetech.springstage.core.web.annotation.PageableDefaults;
import com.qinyetech.springstage.core.web.annotation.PermissionInfo;
import com.qinyetech.springstage.core.web.dto.ResponseResult;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * ClassName: DishessController <br/>
 * Function: dishes [菜品] <br/>
 * date: 2018-11-23 11:45:37 <br/>
 *
 * @author liuwenjin
 * @version  1.0
 * @since JDK 1.8
 */
@RestController
@RequestMapping("/management/dishes/dishess")
@PermissionInfo(parentName ="基础信息管理" ,parentOrder = 10,order = 10,code = "management_dishes:read",name ="菜品",deleteAble = false)
public class DishessController extends BaseManagementController{

	@Autowired
	private DishesService dishesService;
	@Autowired
    private DishesCategoryService dishesCategoryService;
	@Autowired
    private DishesUnitService dishesUnitService;
	@Autowired
    private DishesSpecificationService dishesSpecificationService;
	@Autowired
    private DishesMakeCategoryService dishesMakeCategoryService;
	@Autowired
    private DishesMakeService dishesMakeService;
	@Autowired
    private DishesFeedService dishesFeedService;
	@Autowired
    private DishesFeedCategoryService dishesFeedCategoryService;
	@Autowired
    private DishesSpecificationRelationService dishesSpecificationRelationService;
	@Autowired
    private DishesMakeRelationService dishesMakeRelationService;
	@Autowired
    private DishesFeedRelationService dishesFeedRelationService;
	@Autowired
    private DishesPackageDetailService dishesPackageDetailService;
	@Autowired
    private MaterialService materialService;
	@Autowired
    private PurchaseSpecService purchaseSpecService;
	@Autowired
    private MaterialCostDetailService materialCostDetailService;
	@Autowired
    private StockService stockService;
	@Autowired
    private BrandService brandService;
	@Autowired
    private DishesExtendService dishesExtendService;
    //TODO include的字段,支持jsonPath
	private final String [] keys = {"id","storeId","name","spell","pinyin","no","nameEn","category","unit","weigh","season",
            "printCategoryId","commission","commissionType","commissionValue","futureCost","price","vipPrice","hot","recommend",
            "img","introduction","state","rank","type","packType","priceMode","createAt","specificationRelations","makeRelations",
            "feedRelations","materialId","code","brandId","extend"};

    @RequiresPermissions("management_dishes:show")
    @PermissionInfo(code = "management_dishes:show",name ="查看",deleteAble = false)
    @RequestMapping(method = {RequestMethod.GET, RequestMethod.POST})
    @PageableDefaults(sort = "id=desc")//默认按照id降序
    public ResponseResult<JSONObject> index(Searchable searchable,Long storeId){
        if(storeId==null){
            return fail("查询失败");
        }
        searchable = SearchableUtils.newSearchableWithMerchantFilter(searchable);
        searchable.addSearchParam("storeId_eq",storeId);
        searchable.addSearchParam("type_eq",DishesType.DISHES);
        Page<Dishes> dishesPage = dishesService.findAll(searchable);
        searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        if(CollectionUtils.isNotEmpty(dishesPage.getContent())){
            for (Dishes dishes : dishesPage.getContent()) {
                searchable.addSearchParam("dishesId_eq",dishes.getId());
                dishes.setSpecificationRelations((JSONArray)JSONUtils.include(dishesSpecificationRelationService.findWithSort(searchable),"specName"));
                dishes.setMakeRelations((JSONArray) JSONUtils.include(dishesMakeRelationService.findWithSort(searchable),"name"));
                dishes.setFeedRelations((JSONArray)JSONUtils.include(dishesFeedRelationService.findWithSort(searchable),"name"));
            }
        }
        QyMap map = QyMap.map("dishesPage",JSONUtils.include(dishesPage, keys));
        //菜品类别
        searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        searchable.addSearchParam("no_ne","00000");
        List<DishesCategory> categoryList = dishesCategoryService.findWithSort(searchable);
        map.setv("categoryList",JSONUtils.include(categoryList,new Class[]{State.class},"id","no","name","state"));
        return ok("查询成功", map);
    }

    @GetMapping("/create")
    public ResponseResult<QyMap> _new(Long storeId){
        if(storeId==null){
            return fail("查询失败");
        }
        QyMap map=QyMap.NEW();
        Dishes dishes = new Dishes();
        dishes.setNo(dishesService.getNextNo(DishesType.DISHES, "10001",CurrentAccountUtils.getAuthenticatedMerchantGroupID()));
        map.setv("dishes",JSONUtils.include(dishes, keys));
        map.setv("material",JSONUtils.include(new Material(),"id","no","name","pinyin","spell","categoryId","goodsSpec","unit",
                "minStock","maxStock","storeMode","purchaseNewPrice","consumeUnit","consumeRates","orderPriceBom",
                "orderType","stocktakeType","state","category","storeId","materialType"));
        initFormDate(map,storeId,dishes);
        return ok("初始化成功", map);
    }

    @RequiresPermissions("management_dishes:edit")
    @PermissionInfo(code = "management_dishes:create",name ="新增",deleteAble = false)
    @PostMapping("/create")
    public ResponseResult<String> create(@RequestBody JSONObject data, BindingResult bindingResult){
//        if(dishesService.exists(buildExists(null, "no", dishes.getNo()))){
//             bindingResult.rejectValue("no","no.error","编号已经存在");
//        }
        if (bindingResult.hasErrors()) {
            return super.validateFail(bindingResult);
        }
        QyMap map = dishesService.saveData(data,CurrentAccountUtils.getAuthenticatedMerchantGroupID());
        log.info("map : {}",map);

        //保存原料对应原料类别id
        if(map.getBoolean("flag")){
            dishesService.saveMaterialForCategory(map.getLong("category_id"), map.getLong("material_id"));
            materialService.savePurchaseMaterial(map.getList("ids",Long.class),map.getLong("material_id"));
        }



        return ok("保存成功");
    }

    @GetMapping("/{id}")
    public ResponseResult<JSONObject> show(@ModelAttribute Dishes dishes){
        return ok("查询成功", JSONUtils.include(dishes, keys));
    }

    @GetMapping("/{id}/update")
    public ResponseResult<QyMap> edit(@ModelAttribute Dishes dishes,Long storeId){
        if (storeId==null){
            return fail("查询失败",10001);
        }
        QyMap map=QyMap.NEW();
        map.setv("dishes",JSONUtils.include(dishes, keys));
        //规格
        Searchable searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("dishesId_eq",dishes.getId());
        List<DishesSpecificationRelation> specificationRelationList = dishesSpecificationRelationService.findWithSort(searchable);
        map.setv("specificationRelationList",JSONUtils.include(specificationRelationList,"id","specId","specName","price","vipPrice","def"));
        //做法
        List<DishesMakeRelation> makeRelationList = dishesMakeRelationService.findWithSort(searchable);
        map.setv("makeRelationList",JSONUtils.include(makeRelationList,new Class[]{PriceupType.class},"id","makeCategoryId","makeCategoryName","makeId","name","priceupType","val","def"));
        //加料
        List<DishesFeedRelation> feedRelationList = dishesFeedRelationService.findWithSort(searchable);
        map.setv("feedRelationList",JSONUtils.include(feedRelationList,"id","categoryId","categoryName","feedId","name","price"));

        if(dishes.getMaterialId()!=null){
            log.info("----------->>>> yuanliao : {}",dishes.getMaterialId());
            Material material = materialService.findById(dishes.getMaterialId());
            map.setv("material",JSONUtils.include(material,"id","no","name","pinyin","spell","categoryId","goodsSpec","unit",
                    "minStock","maxStock","storeMode","purchaseNewPrice","consumeUnit","consumeRates","orderPriceBom",
                    "orderType","stocktakeType","state","category","storeId","materialType"));

            log.info("----------->>>>  : {}",material.getName());
            searchable = SearchableUtils.newSearchableWithMerchantFilter();
            searchable.addSearchParam("material.id_eq",material.getId());
            List<PurchaseSpec> currents = purchaseSpecService.findWithSort(searchable);
            map.put("purchase", JSONUtils.include(currents, "id","name:purchaseSpec", "unit:purchaseUnit","ratio:purchaseCount", "price:purchasePrice","hasDef"));
        }
        initFormDate(map,storeId,dishes);
        return ok("查询成功",map);
    }

    @RequiresPermissions("management_dishes:edit")
    @PermissionInfo(code = "management_dishes:update",name ="修改",deleteAble = false)
    @PutMapping("/{id}/update")
    public ResponseResult<String> update(@RequestBody JSONObject data,BindingResult bindingResult){
//        if(dishesService.exists(buildExists(null, "no", dishes.getNo()))){
//             bindingResult.rejectValue("no","no.error","编号已经存在");
//        }
        if (bindingResult.hasErrors()) {
            return super.validateFail(bindingResult);
        }
        QyMap map =  dishesService.saveData(data, CurrentAccountUtils.getAuthenticatedMerchantGroupID());
        log.info("map : {}",map);

        //保存原料对应原料类别id
        if(map.getBoolean("flag")){
            dishesService.saveMaterialForCategory(map.getLong("category_id"), map.getLong("material_id"));
            materialService.savePurchaseMaterial(map.getList("ids",Long.class),map.getLong("material_id"));
        }

        return ok("更新成功", null);
    }

    @RequiresPermissions("management_dishes:destory")
    @PermissionInfo(code = "management_dishes:destory",name ="删除",deleteAble = false)
    @DeleteMapping("/{id}")
    public ResponseResult<String> destory(@PathVariable Long id){
        //是否使用
        Searchable searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("dishesId_eq",id);
        Long count = dishesPackageDetailService.count(searchable);
        if(count.intValue()>0){
            return fail("正在使用，不能删除");
        }
        Dishes dishes = dishesService.findById(id);

        //判断单店的商品是否使用 使用不能删除
        boolean boo = dishesService.deleteBranchDishesData(dishes.getUuid());
        if (!boo){
            return fail("正在使用，不能删除");
        }
//        dishesService.deleteBranchDishesData(dishes);


        if(dishes.getMaterialId()!=null){
//            searchable = SearchableUtils.newSearchableWithMerchantFilter();
//            searchable.addSearchParam("materialId_eq",dishes.getMaterialId());
//            count = materialCostDetailService.count(searchable);
//            if (count.intValue()>0){
//                return fail("商品正在使用,不能删除");
//            }
            //有库存
            searchable = SearchableUtils.newSearchableWithMerchantFilter();
            searchable.addSearchParam("materialId_eq",id);
            count = stockService.count(searchable);
            if (count.intValue()>0){
                return fail("商品有库存，不能删除");
            }
            //加工关系
            Material material = materialService.findById(dishes.getMaterialId());
            if (material.getHasRelation()){
                return fail("已使用，不能删除");
            }
            //删除原料信息
            materialService.logicDelete(dishes.getMaterialId());
        }
        dishes.setUpdateTimestamp(DateUtils.current());
        dishesService.update(dishes);
        dishesService.deletedMaterialCostDetails(id);
        dishesService.logicDelete(id);
        return ok("删除成功", null);
    }


    /**
     * 选择菜品
     * @param storeId
     * @param categoryId
     * @param name
     * @return
     */
    @GetMapping("/getDisheData")
    @PageableDefaults(sort = "id=desc")//默认按照id降序
    public Object getDisheData(Long storeId,Long categoryId,String name,Searchable searchable){
        Page<Map<String,Object>> mapList = dishesService.getDishesData(CurrentAccountUtils.getAuthenticatedMerchantGroupID(),
                storeId,categoryId,name,searchable);
        QyMap map = QyMap.map("dishesData",mapList);
        //菜品类别
        searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId",storeId);
        searchable.addSearchParam("no_ne","00000");
        List<DishesCategory> categoryList = dishesCategoryService.findWithSort(searchable);
        map.setv("categoryList",JSONUtils.include(categoryList,"no","name","state"));
        return ok("查询成功", map);
    }


    /**
     * 根据菜品id获取菜品包含的门店信息
     * @param id
     * @return
     */
    @GetMapping("/getDishesBranchs")
    public Object getDishesBranchs(Long id){
        log.info("id : {} ",id);
        List<Map<String,Object>> mapList = dishesService.getDishesBranchs(id);
        QyMap map = QyMap.map("branchs",mapList);
        return ok("查询成功", map);
    }



    @ModelAttribute
    public void preparedData(@PathVariable(value="id",required = false) String id,Model model){
        if(StringUtils.isNotBlank(id)){ //如果路径中有id参数则查询实体对象
            Dishes dishes = dishesService.findById(Long.valueOf(id));
            model.addAttribute(dishes);
        }
    }

    /**
     * 初始化表单数据
     * @param qyMap
     */
    private void initFormDate(QyMap qyMap,Long storeId,Dishes dishes){
        //在售/停售
        qyMap.setv("dishesStates", DishesState.values());

        //提成类型
        qyMap.setv("dishesCommissionTypes", DishesCommissionType.values());

        //加价方式
        qyMap.setv("priceupTypes",PriceupType.values());

        //商品单位
        Searchable searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        List<DishesUnit> unitList = dishesUnitService.findWithSort(searchable);
        qyMap.setv("unitList",JSONUtils.include(unitList,new Class[]{State.class},"id","name","state"));

        //多规格
        List<DishesSpecification> specificationList = dishesSpecificationService.findWithSort(searchable);
        qyMap.setv("specificationList",JSONUtils.include(specificationList,new Class[]{State.class},"id","name","state"));

        //多做法 列表
        List<DishesMake> dishesMakeList = dishesMakeService.findWithSort(searchable);
        qyMap.setv("dishesMakeList",JSONUtils.include(dishesMakeList,new Class[]{State.class, PriceupType.class},"id","name","priceupType","priceupValue","state","type.id:typeId"));


        //多做法 分类
        List<DishesMakeCategory> makeCategoryList = dishesMakeCategoryService.findWithSort(searchable);
        if(CollectionUtils.isNotEmpty(makeCategoryList)){
            makeCategoryList.forEach(item->{
                log.info("leibie : --- {}",item.getId());
                item.setCount(dishesMakeService.getCountByType(item.getId(),storeId));
                log.info("count - : {}",dishesMakeService.getCountByType(item.getId(),storeId));
            });
        }
        qyMap.setv("makeCategoryList",JSONUtils.include(makeCategoryList,new Class[]{State.class, ChooseType.class},"id","name","chooseType","state","count"));


        //多加料 类别
        List<DishesFeedCategory> feedCategoryList = dishesFeedCategoryService.findWithSort(searchable);
        if(CollectionUtils.isNotEmpty(feedCategoryList)){
            feedCategoryList.forEach(item->{
                item.setCount(dishesFeedService.getCountByCategoryId(item.getId(),storeId));
            });
        }
        feedCategoryList = feedCategoryList.stream().filter(x->x.getCount()>0).collect(Collectors.toList());
        qyMap.setv("feedCategoryList",JSONUtils.include(feedCategoryList,new Class[]{State.class},"id","name","state","count"));

        //多加料
        List<DishesFeed> feedList = dishesFeedService.findWithSort(searchable);
        qyMap.setv("feedList",JSONUtils.include(feedList,"id","name","price","state","type.id:typeId","type.name:typeName"));

        //菜品类别
        searchable.addSearchParam("no_ne","00000");
        List<DishesCategory> categoryList = dishesCategoryService.findWithSort(searchable);
        qyMap.setv("categoryList",JSONUtils.include(categoryList,new Class[]{State.class},"id","no","name","state"));

        qyMap.setv("stocktakeTypes", InventoryType.values())
                .setv("orderTypes", OrderType.values())
                .setv("storeModes", StoreMode.values());

        searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        List<Brand> brands =brandService.findWithSort(searchable);
        qyMap.setv("brands",JSONUtils.include(brands,"id","name"));



        searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        List<DishesExtend> dishesExtendList = dishesExtendService.findWithSort(searchable);
        List<QyMap> dishesExtends = Lists.newArrayList();

        JSONArray extendArray = new JSONArray();
        if(dishes!=null && StringUtils.isNotBlank(dishes.getExtend())){
            extendArray = JSON.parseArray(dishes.getExtend());
        }
        for(DishesExtend item : dishesExtendList){
            String value = "";
            if(CollectionUtils.isNotEmpty(extendArray)){
                for(int i=0;i<extendArray.size();i++){
                    JSONObject extendItem = extendArray.getJSONObject(i);
                    if(item.getName().equals(extendItem.getString("name"))){
                        value = extendItem.getString("value");
                        break;
                    }
                }
            }
            dishesExtends.add(QyMap.NEW().setv("name", item.getName()).setv("value", value));
        }
        qyMap.setv("dishesExtends",dishesExtends);


    }


    /**
     * 保存某菜品库中的商品信息
     * @param storeId 菜品库id
     * @return
     */
    @GetMapping("/saveStoreInfos")
    public Object saveStoreTestInfos(Long storeId,Long merchantGroupId){
        dishesService.saveStoreTestInfos(storeId,merchantGroupId);
        return ok("查询成功");
    }


    @RequestMapping("/queryDishesExtends")
    public Object queryDishesExtends(Long storeId){
        Searchable searchable = SearchableUtils.newSearchableWithMerchantFilter();
        searchable.addSearchParam("storeId_eq",storeId);
        List<DishesExtend> dishesExtends = dishesExtendService.findWithSort(searchable);
        return ok("查询成功", BeanConvertUtil.listToDataTable(dishesExtends, "id", "name"));
    }

    @PostMapping("/saveDishesExtends")
    public Object saveDishesExtends(@RequestBody JSONObject json){
        dishesExtendService.saveAll(json,CurrentAccountUtils.getAuthenticatedMerchantGroupID());
        return ok("保存成功");
    }

    /**
     * 根据菜品id获取菜品包含的门店信息
     * @param
     * @return
     */
    @GetMapping("/verifyCode")
    public Object verifyCode(String code,Long storeId,Long dishesId){
        boolean boo = dishesService.verifyCode(storeId,code,CurrentAccountUtils.getAuthenticatedMerchantGroupID(),dishesId);
        return ok("查询成功", boo);
    }


}